<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
		<style>
			body,
			html {
				padding: 0;
				margin: 0;
				width: 100%;
				height: 100%;
				overflow: hidden;
				display: flex;
				flex-direction: column;
			}

			.header {
				position: relative;
				padding-top: 10px;
				color: #0066BF;
				line-height: 20px;
				height: 20px;
				font-size: 20px;
				padding-left: 15px;
			}

			.body {
				flex: 1;
				display: flex;
				flex-direction: row;
			}

			#container {
				border: 1px solid #a6d86b;
				box-sizing: border-box;
				flex: 1;
				padding: 15px 3px;
				box-shadow: inset 0px 0px 5px 1px #a6d86b;
			}

			.exsample {
				width: 300px;
				line-height: 30px;
				padding-top: 20px;
			}

			.code {
				height: 100%;
				display: flex;
				flex-direction: column;
				flex: 1;
				box-sizing: border-box;
				padding: 15px;
			}
			.err{
				color: red;
			}

			.print {
				padding-top: 10px;
				height: 30px;
				line-height: 30px;
				color: #0066BF;
			}

			.console {
				height: 200px;
				box-shadow: inset 0px 0px 5px 1px #0066BF;
				overflow-y: auto;
			}

			.space {
				height: 50px;
			}
		</style>
	</head>
	<body>
		<div class="header">
			数学编程猫
			<button id="run">运行</button>
			</div>
		<div class="body">
			<div class="code">
				<div id="container"></div>
				<div class="print">输出<button onclick="javascript:document.getElementById('console').innerHTML='';" style="margin-left:10px ;">清空</button></div>
				<div id="console" class="console"></div>
				<div class="space"></div>
			</div>
			<div class="exsample">
				<div><a id="exs1" href="javascript:;">计算从1加到100</a></div>
				<div><a id="exs2" href="javascript:;">计算数列1 1 2 3 8 11... 第15项</a></div>
				<div><a id="exs3" href="javascript:;">用加减乘除开平方</a></div>
			</div>
		</div>
		<script src="tokeniser.js"></script>
		<script src="ast.js"></script>
		<script src="vm.js"></script>
		<script src="monaco-editor/min/vs/loader.js"></script>
		<script>
			require.config({
				paths: {
					'vs': 'monaco-editor/min/vs'
				}
			});
			require.config({
				'vs/nls': {
					availableLanguages: {
						'*': 'zh-cn'
					}
				}
			});
			require(['vs/editor/editor.main'], function() {
				monaco.languages.register({
					id: "mylang"
				});
				monaco.editor.defineTheme("myTheme", {
					//基础
					base: "vs",
					//继承
					inherit: true,
					//规则
					rules: [{
							token: "my-built-in-function",
							foreground: "#900000",
							fontStyle: 'bold'
						},
						{
							token: "my-keyword",
							foreground: "#0086b3"
						},
						{
							token: "my-function",
							foreground: "#098658"
						},
					],
				});
				monaco.languages.setMonarchTokensProvider("mylang", {
					tokenizer: {
						root: [
							[/[{}()\[\]]/, '@brackets'],

							[/\b\d*\.\d+([eE][\-+]?\d+)?\b/, "number.float"],
							[/\b0[xX][0-9a-fA-F]+\b/, "number.hex"],
							[/\b\d+\b/, "number"],

							[/\b(if|elseif|else|return|while|print|fun|dim)\b/, "my-keyword"],

							[/\b(and|or)\b/, "my-built-in-function"],

							[/([a-zA-Z0-9_]+)\s*(\(.*\))/, "@rematch", "@matchfunc"],
							{
								include: "@whitespace"
							},
						],
						matchfunc: [
							[/([a-zA-Z0-9_]+)/, {
								token: "my-function",
								next: "@popall"
							}],
						],
						whitespace: [
							[/[ \t\r\n]+/, "white"],
							[/#.*$/, "comment"],
						],
					},
					//语言大小写不敏感吗
					ignoreCase: false,
				});
				monaco.languages.setLanguageConfiguration("mylang", {
					brackets: [
						["{", "}"],
						["[", "]"],
						["(", ")"],
					],
					autoClosingPairs: [{
							open: "{",
							close: "}"
						},
						{
							open: "[",
							close: "]"
						},
						{
							open: "(",
							close: ")"
						},
						{
							open: "'",
							close: "'",
							notIn: ["string", "comment"]
						}
					],
				});
				var editor = monaco.editor.create(document.getElementById("container"), {
					language: "mylang",
					theme: "myTheme",
					wordWrapColumn: 120,
					wordWrapMinified: true,
					minimap: {
						enabled: false, // 不要小地图
					}
				});
				document.getElementById("run").addEventListener("click",function(){
					try{
						var code = editor.getValue();
						var tonkes = Tokeniser(code);
						var ast = Ast(tonkes)
						Vm(ast,function(result){
							document.getElementById('console').innerHTML += `<div><span class="ok">>>>${result}</span></div>`
						})
					}catch(e){
						document.getElementById('console').innerHTML += `<div><span class="err">>>${e.message}</span></div>`
					}
				})
				
				document.getElementById('exs1').addEventListener("click",function(){
					editor.setValue(`dim r;
dim i;
r:=0;
i:=1;
while(i<=100) {
    r := r +i;
    i :=i+1;
}
print(r);`);
				});
				document.getElementById('exs2').addEventListener("click",function(){
									editor.setValue(`fun count(c){
  dim t;
  if(c<=2) {
    t:=1;
  }else{
   t:=count(c-2)+count(c-1);
  }
  return t;
}
print(count(15));`);
								});
							document.getElementById('exs3').addEventListener("click",function(){
																editor.setValue(`fun square(num,loop) {
    dim r;
    dim min;
    dim max;
    dim i;
    r:=0;
    min := 0;
    max := num;
    i := 0;
    while(i<=loop) {
        dim mid;
        mid:=(min+max) /2;
        if(mid*mid > num) {
            max :=mid;
        } else {
            min :=mid;
        }
        i:= i + 1;
        r:=mid;
        print(r);
    }
    return r;
}
print(square(2,30));`);
															})
			});
		</script>
	</body>
</html>
